package cn.vshare.Realm;

import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.Filter;
import java.util.LinkedHashMap;
import java.util.Map;

@Configuration
public class ShiroConfig {

    /*
    * 20181016wyl
    * spring-shiro.xml的代码实现,两者等效
    * 定义本类的目的:将spring-shiro.xml的内容转化为代码实现,以便和Spring_boot整合
    *按照 spring-shiro.xml的内容顺序进行逐一转化
    * 切记:细心
    *
    * */


    /*
    * 0-自定义的shiro过滤器(拦截器),目的是截取到未授权的URL,已备其他处理
    * 0-有3个类:解析类,过滤器类
    * */
    @Bean
    public ResourceCheckFilter resourceCheckFilter111(){
        ResourceCheckFilter resourceCheckFilter=new ResourceCheckFilter();
        resourceCheckFilter.setErrorUrl("/toFail.do");
        return resourceCheckFilter;
    }

    @Bean
    public UrlPermission urlPermission111(){
        UrlPermission urlPermission=new UrlPermission();
        return urlPermission;
    }

    @Bean
    public UrlPermissionResolver urlPermissionResolver111(){
        UrlPermissionResolver urlPermissionResolver=new UrlPermissionResolver();
        return urlPermissionResolver;
    }


    /*
    * 1-自定义Realm实现
    * */
    @Bean
    public CustomRealm customRealm111(){
        CustomRealm customRealm=new CustomRealm();
        customRealm.setPermissionResolver(urlPermissionResolver111());
        return customRealm;
    }

    /*
    * 2-securityManager
    *
    * */

    @Bean
    public SecurityManager securityManager111(){
        DefaultWebSecurityManager defaultWebSecurityManager=new DefaultWebSecurityManager();
        //注入1-自定义Realm
        defaultWebSecurityManager.setRealm(customRealm111());
        return defaultWebSecurityManager;

    }

    /*
    *3- 保证实现了shiro内部Lifecycle函数的bean的执行  （生命周期）
    * */
    @Bean
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor111(){
        LifecycleBeanPostProcessor lifecycleBeanPostProcessor=new LifecycleBeanPostProcessor();
        return lifecycleBeanPostProcessor;
    }

    /*
    * 4- Shiro Filter 拦截器相关配置
    * */
    @Bean
    public ShiroFilterFactoryBean shiroFilter111(SecurityManager securityManager){
        ShiroFilterFactoryBean shiroFilterFactoryBean=new ShiroFilterFactoryBean();

        //1-shiro的安全接口，必须配置的属性
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        //2-登录成功后跳转到的链接
        // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
        shiroFilterFactoryBean.setLoginUrl("/login.html");
        //3-前后台不同,故不设置
        // 登录成功后要跳转的链接
        //shiroFilterFactoryBean.setSuccessUrl("");//不设置
        //4-未授权界面;由近及远原则
        shiroFilterFactoryBean.setUnauthorizedUrl("/toFail.do");


        //5-自定义过滤器,
        // 等同于package org.apache.shiro.web.filter.mgt.DefaultFilter(ano,authc等)
        //ShiroFilterFactoryBean.java:38
        Map<String,Filter>filters111=new LinkedHashMap<>();
        filters111.put("resourceCheckFilter222",resourceCheckFilter111());//ShiroConfig.java:40
        //属性的赋值
        shiroFilterFactoryBean.setFilters(filters111);

        //6- 过滤链定义 ,从上往下顺序执行,一般将/**放在最下面执行
        //ShiroFilterFactoryBean.java:39
        //拦截器链
        Map<String,String>filterChainDefinitionMap111=new LinkedHashMap<>();


        //6.1- 配置不会被拦截的链接 顺序判断

        // 配置退出过滤器,其中的具体的退出代码Shiro已经替我们实现了
        //filterChainDefinitionMap111.put("/logout", "logout");//本项目不使用


        //<!--前台的权限过滤器链-->
        filterChainDefinitionMap111.put("/login.html","anon");
        filterChainDefinitionMap111.put("/register.html","anon");
        filterChainDefinitionMap111.put("/index.html","anon");

        //<!--anon匿名访问-->
        filterChainDefinitionMap111.put("/queryAllKind.do","anon");
        filterChainDefinitionMap111.put("/getKindVideos.do","anon");
        filterChainDefinitionMap111.put("/getLikeVideos.do","anon");
        filterChainDefinitionMap111.put("/getVideos.do","anon");
        filterChainDefinitionMap111.put("/queryVideoByKind.do","anon");
        filterChainDefinitionMap111.put("/queryVideoByvid.do","anon");

        //<!--需要认证登录-->
        filterChainDefinitionMap111.put("/toIndex.do","resourceCheckFilter111");
        filterChainDefinitionMap111.put("/changeAccount.do","resourceCheckFilter111,perms[/changeAccount.do]");
        filterChainDefinitionMap111.put("/logoff.do","resourceCheckFilter111,perms[/logoff.do]");
        
        //<!--弹幕的加载和新增-->
        filterChainDefinitionMap111.put("/getBarrageList.do","resourceCheckFilter111,perms[/getBarrageList.do]");
        //<!--打赏金币功能-->
        filterChainDefinitionMap111.put("/rewardToUser.do","resourceCheckFilter111,perms[/rewardToUser.do]");
        
        //<!--视频的收藏功能-->
        filterChainDefinitionMap111.put("/addFavorite.do","resourceCheckFilter111,perms[/addFavorite.do]");
        //<!--视频是否已经被收藏的功能-->
        filterChainDefinitionMap111.put("/queryIsFavoriter.do","resourceCheckFilter111,perms[/queryIsFavoriter.do]");
        //<!--对视频的评论功能-->
        filterChainDefinitionMap111.put("/addComment.do","resourceCheckFilter111,perms[/addComment.do]");
        filterChainDefinitionMap111.put("/updateCommentAddLike.do","resourceCheckFilter111,perms[/updateCommentAddLike.do]");
        filterChainDefinitionMap111.put("/updateCommentCancelLike.do","resourceCheckFilter111,perms[/updateCommentCancelLike.do]");
        //<!--对评论的回复功能-->
        filterChainDefinitionMap111.put("/addReply.do","resourceCheckFilter111,perms[/addReply.do]");
        filterChainDefinitionMap111.put("/updateReplyAddLike.do","resourceCheckFilter111,perms[/updateReplyAddLike.do]");
        filterChainDefinitionMap111.put("/updateReplyCancelLike.do","resourceCheckFilter111,perms[/updateReplyCancelLike.do]");
        //<!--我的历史足迹-->
        filterChainDefinitionMap111.put("/getFootPoint.do","resourceCheckFilter111,perms[/getFootPoint.do]");
        
        
        //<!--后台的权限过滤器链-->
        //跳转至后台首页
        filterChainDefinitionMap111.put("/toAdminFtl.do","resourceCheckFilter111,perms[/toAdminFtl.do]");
        //<!--角色-->
        //<!--admin-role.ftl-->
        filterChainDefinitionMap111.put("/delete2Array2Role","resourceCheckFilter111,perms[/delete2Array2Role.do]");
        filterChainDefinitionMap111.put("/addRole.do","resourceCheckFilter111,perms[/addRole");
        filterChainDefinitionMap111.put("/getRoleById.do","resourceCheckFilter111,perms[/getRoleById.do]");
        filterChainDefinitionMap111.put("/deleteRole","resourceCheckFilter111,perms[/deleteRole.do]");
        //<!--一级权限-->
        //<!--admin-permission-first.ftl-->
        filterChainDefinitionMap111.put("/delete2Array2PermissionFirst","resourceCheckFilter111,perms[/delete2Array2PermissionFirst.do]");
        filterChainDefinitionMap111.put("/addPermissionFirst.do","resourceCheckFilter111,perms[/addPermissionFirst");
        filterChainDefinitionMap111.put("/getPermissionFirstById.do","resourceCheckFilter111,perms[/getPermissionFirstById.do]");
        filterChainDefinitionMap111.put("/deletePermissionFirst","resourceCheckFilter111,perms[/deletePermissionFirst.do]");
        //<!--二级权限-->
        //<!--admin-permission-second.ftl-->
        filterChainDefinitionMap111.put("/delete2Array2PermissionSecond","resourceCheckFilter111,perms[/delete2Array2PermissionSecond.do]");
        filterChainDefinitionMap111.put("/addPermissionSecond.do","resourceCheckFilter111,perms[/addPermissionSecond");
        filterChainDefinitionMap111.put("/getPermissionSecondById.do","resourceCheckFilter111,perms[/getPermissionSecondById.do]");
        filterChainDefinitionMap111.put("/deletePermissionSecond","resourceCheckFilter111,perms[/deletePermissionSecond.do]");

        //属性的赋值
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap111);

        return shiroFilterFactoryBean;//spring-shiro.xml的代码实现,两者等效
    }

}


/*
* 20181016wyl
* 介是个栗子:
* 拦截器.

		// 配置不会被拦截的链接 顺序判断
		filterChainDefinitionMap.put("/static/**", "anon");
		filterChainDefinitionMap.put("/ajaxLogin", "anon");

		// 配置退出过滤器,其中的具体的退出代码Shiro已经替我们实现了
		filterChainDefinitionMap.put("/logout", "logout");
		filterChainDefinitionMap.put("/add", "perms[权限添加]");

		// <!-- 过滤链定义，从上向下顺序执行，一般将 /**放在最为下边 -->:这是一个坑呢，一不小心代码就不好使了;
		// <!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问-->
		filterChainDefinitionMap.put("/**", "authc");

		shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
		System.out.println("Shiro拦截器工厂类注入成功");
		return shiroFilterFactoryBean;
*
* */

/**
 * ShiroFilterFactoryBean 处理拦截资源文件问题。
 * 注意：单独一个ShiroFilterFactoryBean配置是或报错的，以为在
 * 初始化ShiroFilterFactoryBean的时候需要注入：SecurityManager
 *
 * Filter Chain定义说明
 * 1、一个URL可以配置多个Filter，使用逗号分隔
 * 2、当设置多个过滤器时，全部验证通过，才视为通过
 * 3、部分过滤器可指定参数，如perms，roles
 *
 */